/*
 *  Copyright 2011 yuxinlei.
 * 
 *  Licensed under the Apache License, Version 2.0 (the "License");
 *  you may not use this file except in compliance with the License.
 *  You may obtain a copy of the License at
 * 
 *       http://www.apache.org/licenses/LICENSE-2.0
 * 
 *  Unless required by applicable law or agreed to in writing, software
 *  distributed under the License is distributed on an "AS IS" BASIS,
 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *  See the License for the specific language governing permissions and
 *  limitations under the License.
 *  under the License.
 */

package camel.first.api.datastore.internal.dao.impl;

import camel.first.api.datastore.dao.BuildsEntityJpaController;
import camel.first.api.datastore.dao.exceptions.IllegalOrphanException;
import camel.first.api.datastore.dao.exceptions.NonexistentEntityException;
import camel.first.api.datastore.dao.exceptions.PreexistingEntityException;
import camel.first.api.datastore.internal.entity.BuildsEntity;
import java.util.List;
import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.Persistence;
import javax.persistence.Query;
import javax.persistence.EntityNotFoundException;
import camel.first.api.datastore.internal.entity.ProjectsEntity;
import camel.first.api.datastore.internal.entity.CoverageEntity;
import java.util.ArrayList;

/**
 *
 * @author yuxinlei
 */
public class BuildsEntityJpaControllerImpl implements BuildsEntityJpaController {

    public BuildsEntityJpaControllerImpl() {
        emf = Persistence.createEntityManagerFactory("reportdb");
    }
    private EntityManagerFactory emf = null;

    public EntityManager getEntityManager() {
        return emf.createEntityManager();
    }

    public void create(BuildsEntity buildsEntity) throws PreexistingEntityException, Exception {
        EntityManager em = null;
        try {
            em = getEntityManager();
            em.getTransaction().begin();
            ProjectsEntity projectsByProjectId = buildsEntity.getProjectsByProjectId();
            if (projectsByProjectId != null) {
                projectsByProjectId = em.getReference(projectsByProjectId.getClass(), projectsByProjectId.getId());
                buildsEntity.setProjectsByProjectId(projectsByProjectId);
            }
            CoverageEntity coverageById = buildsEntity.getCoverageById();
            if (coverageById != null) {
                coverageById = em.getReference(coverageById.getClass(), coverageById.getBuildId());
                buildsEntity.setCoverageById(coverageById);
            }
            em.persist(buildsEntity);
            if (projectsByProjectId != null) {
                projectsByProjectId.getBuildsesById().add(buildsEntity);
                projectsByProjectId = em.merge(projectsByProjectId);
            }
            if (coverageById != null) {
                BuildsEntity oldBuildsByBuildIdOfCoverageById = coverageById.getBuildsByBuildId();
                if (oldBuildsByBuildIdOfCoverageById != null) {
                    oldBuildsByBuildIdOfCoverageById.setCoverageById(null);
                    oldBuildsByBuildIdOfCoverageById = em.merge(oldBuildsByBuildIdOfCoverageById);
                }
                coverageById.setBuildsByBuildId(buildsEntity);
                coverageById = em.merge(coverageById);
            }
            em.getTransaction().commit();
        } catch (Exception ex) {
            if (findBuildsEntity(buildsEntity.getId()) != null) {
                throw new PreexistingEntityException("BuildsEntity " + buildsEntity + " already exists.", ex);
            }
            throw ex;
        } finally {
            if (em != null) {
                em.close();
            }
        }
    }

    public void edit(BuildsEntity buildsEntity) throws IllegalOrphanException, NonexistentEntityException, Exception {
        EntityManager em = null;
        try {
            em = getEntityManager();
            em.getTransaction().begin();
            BuildsEntity persistentBuildsEntity = em.find(BuildsEntity.class, buildsEntity.getId());
            ProjectsEntity projectsByProjectIdOld = persistentBuildsEntity.getProjectsByProjectId();
            ProjectsEntity projectsByProjectIdNew = buildsEntity.getProjectsByProjectId();
            CoverageEntity coverageByIdOld = persistentBuildsEntity.getCoverageById();
            CoverageEntity coverageByIdNew = buildsEntity.getCoverageById();
            List<String> illegalOrphanMessages = null;

            if (coverageByIdOld != null && !coverageByIdOld.equals(coverageByIdNew)) {
                if (illegalOrphanMessages == null) {
                    illegalOrphanMessages = new ArrayList<String>();
                }
                illegalOrphanMessages.add("You must retain CoverageEntity " + coverageByIdOld + " since its buildsByBuildId field is not nullable.");
            }
            if (illegalOrphanMessages != null) {
                throw new IllegalOrphanException(illegalOrphanMessages);
            }
            if (projectsByProjectIdNew != null) {
                projectsByProjectIdNew = em.getReference(projectsByProjectIdNew.getClass(), projectsByProjectIdNew.getId());
                buildsEntity.setProjectsByProjectId(projectsByProjectIdNew);
            }
            if (coverageByIdNew != null) {
                coverageByIdNew = em.getReference(coverageByIdNew.getClass(), coverageByIdNew.getBuildId());
                buildsEntity.setCoverageById(coverageByIdNew);
            }
            buildsEntity = em.merge(buildsEntity);
            if (projectsByProjectIdOld != null && !projectsByProjectIdOld.equals(projectsByProjectIdNew)) {
                projectsByProjectIdOld.getBuildsesById().remove(buildsEntity);
                projectsByProjectIdOld = em.merge(projectsByProjectIdOld);
            }
            if (projectsByProjectIdNew != null && !projectsByProjectIdNew.equals(projectsByProjectIdOld)) {
                projectsByProjectIdNew.getBuildsesById().add(buildsEntity);
                projectsByProjectIdNew = em.merge(projectsByProjectIdNew);
            }
            if (coverageByIdNew != null && !coverageByIdNew.equals(coverageByIdOld)) {
                BuildsEntity oldBuildsByBuildIdOfCoverageById = coverageByIdNew.getBuildsByBuildId();
                if (oldBuildsByBuildIdOfCoverageById != null) {
                    oldBuildsByBuildIdOfCoverageById.setCoverageById(null);
                    oldBuildsByBuildIdOfCoverageById = em.merge(oldBuildsByBuildIdOfCoverageById);
                }
                coverageByIdNew.setBuildsByBuildId(buildsEntity);
                coverageByIdNew = em.merge(coverageByIdNew);
            }
            em.getTransaction().commit();
        } catch (Exception ex) {
            String msg = ex.getLocalizedMessage();
            if (msg == null || msg.length() == 0) {
                int id = buildsEntity.getId();
                if (findBuildsEntity(id) == null) {
                    throw new NonexistentEntityException("The buildsEntity with id " + id + " no longer exists.");
                }
            }
            throw ex;
        } finally {
            if (em != null) {
                em.close();
            }
        }
    }

    public void destroy(int id) throws IllegalOrphanException, NonexistentEntityException {
        EntityManager em = null;
        try {
            em = getEntityManager();
            em.getTransaction().begin();
            BuildsEntity buildsEntity;
            try {
                buildsEntity = em.getReference(BuildsEntity.class, id);
                buildsEntity.getId();
            } catch (EntityNotFoundException enfe) {
                throw new NonexistentEntityException("The buildsEntity with id " + id + " no longer exists.", enfe);
            }
            List<String> illegalOrphanMessages = null;
            CoverageEntity coverageByIdOrphanCheck = buildsEntity.getCoverageById();
            if (coverageByIdOrphanCheck != null) {
                if (illegalOrphanMessages == null) {
                    illegalOrphanMessages = new ArrayList<String>();
                }
                illegalOrphanMessages.add("This BuildsEntity (" + buildsEntity + ") cannot be destroyed since the CoverageEntity " + coverageByIdOrphanCheck + " in its coverageById field has a non-nullable buildsByBuildId field.");
            }
            if (illegalOrphanMessages != null) {
                throw new IllegalOrphanException(illegalOrphanMessages);
            }
            ProjectsEntity projectsByProjectId = buildsEntity.getProjectsByProjectId();
            if (projectsByProjectId != null) {
                projectsByProjectId.getBuildsesById().remove(buildsEntity);
                projectsByProjectId = em.merge(projectsByProjectId);
            }
            em.remove(buildsEntity);
            em.getTransaction().commit();
        } finally {
            if (em != null) {
                em.close();
            }
        }
    }


    public BuildsEntity findBuildsEntity(int id) {
        EntityManager em = getEntityManager();
        try {
            return em.find(BuildsEntity.class, id);
        } finally {
            em.close();
        }
    }



    public List<String> findProjectAllBuildsNumber(ProjectsEntity projectsEntity) {
        EntityManager em = getEntityManager();
        try {
            Query query = em.createNativeQuery("select b.build_num from builds b where b.project_id = :project_id"  );
            query.setParameter("project_id", projectsEntity.getId());
            List<String> builds = query.getResultList();
            return builds;
        } finally {
            em.close();
        }
    }



}
